home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Visual Database / Visual BASIC 5.0 (Ent. Edition) / Vb5ent Extractor.EXE / VB / SAMPLES / COMPTOOL / ACTVCOMP / COFFEE / MTCOFFEE.CLS < prev    next >
Encoding:
Visual Basic class definition  |  1996-12-04  |  7.6 KB  |  240 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. END
  5. Attribute VB_Name = "Coffee"
  6. Attribute VB_GlobalNameSpace = False
  7. Attribute VB_Creatable = True
  8. Attribute VB_PredeclaredId = False
  9. Attribute VB_Exposed = True
  10. Option Explicit
  11. Private Declare Function timeGetTime Lib "winmm.dll" () As Long
  12.  
  13. ' The Coffee object represents a different style
  14. '   of asynchronous notifications from those
  15. '   performed by the CoffeeMonitors.  Instead
  16. '   of periodic notifications Coffee provides
  17. '   progress reports on a long task, and a
  18. '   completion event.
  19. '
  20. ' The mechanism used for these notifications
  21. '   is to raise events.  You could also use
  22. '   call-back methods, and in fact there are
  23. '   advantages to doing so.  Call-backs would
  24. '   allow a component to deal intelligently
  25. '   with errors in the client, whereas events
  26. '   don't return client errors.  This is
  27. '   discussed in "When to Use Events or
  28. '   Call-Backs for Notifications," in Books
  29. '   Online.
  30.  
  31. ' Number of iterations to perform in the dummy
  32. '   task.
  33. Private mlngIterations As Long
  34.  
  35. ' XTimer is used to kick the long task off
  36. '   asynchronously.
  37. Private WithEvents mwXTimer As XTimer
  38. Attribute mwXTimer.VB_VarHelpID = -1
  39.  
  40. Event Progress(ByVal PercentDone As Single, _
  41.         ByRef Cancel As Boolean)
  42. Event Complete(ByVal Canceled As Boolean)
  43.         
  44. ' ThreadID returns the system thread ID of
  45. ' --------      the thread the object was
  46. '   created on.
  47. '
  48. Public Property Get ThreadID() As Long
  49.     ThreadID = App.ThreadID
  50. End Property
  51.  
  52. ' NumberOnThread returns the number of Coffee
  53. ' --------------    objects running on this
  54. '   thread.  This is just the value of the
  55. '   global data variable glngGlobalData, which
  56. '   Coffee objects increment in their Initialize
  57. '   events and decrement in their Terminate
  58. '   events.
  59. '
  60. ' If MTCoffee was compiled with Thread Per
  61. '   Object, the only way for multiple objects
  62. '   to share a thread (and the instance of
  63. '   global data associated with it) is if
  64. '   another Coffee has been created on this
  65. '   thread by calling GetCoffeeOnSameThread.
  66. '
  67. ' If MTCoffee was compiled with a Thread Pool
  68. '   and the count of active objects exceeded
  69. '   the number of threads in the pool, then
  70. '   Coffee objects will be sharing threads.
  71. '
  72. Public Property Get NumberOnThread() As Long
  73.     NumberOnThread = glngGlobalData
  74. End Property
  75.  
  76. ' StartLongTask sets things up for the long
  77. ' -------------     dummy task.  The task is
  78. '   actually started by a code-only XTimer
  79. '   that StartLongTask sets running.
  80. '
  81. Public Sub StartLongTask(ByVal Iterations As Long)
  82.     ' This is a short circuit for testing call
  83.     '   overhead.  See CallAnotherCoffee.
  84.     If Iterations = 0 Then Exit Sub
  85.     '
  86.     ' Store the size of the dummy task.
  87.     mlngIterations = Iterations
  88.     '
  89.     ' Give the timer a short
  90.     '   interval, and set it running just
  91.     '   before returning.
  92.     mwXTimer.Interval = 55
  93.     mwXTimer.Enabled = True
  94. End Sub
  95.  
  96. ' GetCoffeeOnSameThread creates a new Coffee
  97. ' ---------------------     object on the same
  98. '   thread, simulating the effects of thread
  99. '   pooling.  This can only be done internally,
  100. '   as explained in "How Object Creation Works
  101. '   in Visual Basic" in Books Online.
  102. '
  103. Public Function GetCoffeeOnSameThread() As Coffee
  104.     ' All objects created using New will be on
  105.     '   the creator's thread, even a new
  106.     '   Coffee object.
  107.     Set GetCoffeeOnSameThread = New Coffee
  108. End Function
  109.  
  110. ' GetCoffeeOnNewThread creates a new Coffee
  111. ' --------------------     object on a new
  112. '   thread, by calling CreateObject to create
  113. '   the new Coffee object.  The difference
  114. '   between this and the internal creation
  115. '   done by GetCoffeeOnSameThread is explained
  116. '   in "How Object Creation Works in Visual
  117. '   Basic" in Books Online.
  118. '
  119. ' Note that this technique could be used to
  120. '   create objects on different threads that
  121. '   could communicate with each other, without
  122. '   the client having to pass one object a
  123. '   reference to the other (as CoffeeWatch
  124. '   does).  If you experiment with this,
  125. '   remember that the overhead of marshaling
  126. '   calls between threads is almost as great
  127. '   as the overhead of marshaling calls
  128. '   across processes.
  129. '
  130. Public Function GetCoffeeOnNewThread() As Coffee
  131.     ' Create as if by external client.
  132.     Set GetCoffeeOnNewThread = CreateObject("MTCoffee.Coffee")
  133. End Function
  134.  
  135. ' CallAnotherCoffee gives a rough measure of
  136. ' -----------------     cross-thread call
  137. '   overhead.  Pass it a Coffee object on
  138. '   another thread, or on the same thread,
  139. '   and compare the results; the method
  140. '   makes dummy calls to StartLongTask, so
  141. '   that it's essentially measuring only
  142. '   the call overhead.
  143. '
  144. Public Function CallAnotherCoffee(ByVal cfe As Coffee) As Double
  145.     Const TRIES = 10000
  146.     Dim timeStart As Long
  147.     Dim timeEnd As Long
  148.     Dim lngTries As Long
  149.     
  150.     timeStart = timeGetTime
  151.     For lngTries = 1 To TRIES
  152.         cfe.StartLongTask 0
  153.     Next
  154.     timeEnd = timeGetTime
  155.     '
  156.     ' Return seconds (ss.mmm) per call.  (This
  157.     '   will give an incorrect result if you
  158.     '   happen to run CallAnotherCoffee just
  159.     '   as the system timer is rolling over
  160.     '   to zero.)
  161.     CallAnotherCoffee = ((CDbl(timeEnd) - timeStart) / 1000#) / TRIES
  162. End Function
  163.  
  164. Private Sub Class_Initialize()
  165.     ' Increment the global count (that is,
  166.     '   for this thread) of Coffee objects.
  167.     glngGlobalData = glngGlobalData + 1
  168.     '
  169.     ' Create a timer object.
  170.     Set mwXTimer = New XTimer
  171. End Sub
  172.  
  173. Private Sub Class_Terminate()
  174.     ' Decrement the global count (that is,
  175.     '   for this thread) of Coffee objects.
  176.     glngGlobalData = glngGlobalData - 1
  177.     '
  178.     ' Free the timer object.
  179.     Set mwXTimer = Nothing
  180. End Sub
  181.  
  182. Private Sub mwXTimer_Tick()
  183.     ' First thing, turn off the timer.
  184.     mwXTimer.Enabled = False
  185.     Call LongTask
  186. End Sub
  187.  
  188. ' The dummy task.
  189. '
  190. Private Sub LongTask()
  191.     Dim dblDummy As Double
  192.     Dim lngCt As Long
  193.     Dim sngNextMark As Single
  194.     Dim blnCancel As Boolean
  195.     
  196.     ' For small transactions, don't bother to
  197.     '   call back while running.
  198.     If mlngIterations < 100000 Then
  199.         sngNextMark = 1!
  200.     Else
  201.         sngNextMark = 0.1!
  202.     End If
  203.         
  204.     ' This is just a time-waster.
  205.     For lngCt = 1 To mlngIterations
  206.         ' If this were a real application, a
  207.         '   unit of work would be done here.
  208.         '   You may find it interesting to
  209.         '   replace this processor-intensive
  210.         '   activity with one that waits on
  211.         '   the system a lot, such as calls
  212.         '   to a database on another machine,
  213.         '   or reading a very large file.
  214.         '   Throughput on a single-processor
  215.         '   workstation is far greater when
  216.         '   most threads are blocked,
  217.         '   waiting for file input or the
  218.         '   result of a database call.
  219.         '
  220.         dblDummy = 3033.14159 * 2081.14159 * 1138.14159
  221.         '
  222.         If CDbl(lngCt) / mlngIterations > sngNextMark Then
  223.             RaiseEvent Progress(sngNextMark, blnCancel)
  224.             If blnCancel Then
  225.                 ' If the client is tired of waiting
  226.                 '   and wants the task canceled,
  227.                 '   raise the Complete event with
  228.                 '   True (canceled).
  229.                 RaiseEvent Complete(True)
  230.                 Exit Sub
  231.             End If
  232.             sngNextMark = sngNextMark + 0.1!
  233.         End If
  234.     Next
  235.     ' On successful completion, raise the
  236.     '   Complete event with False (not
  237.     '   canceled).
  238.     RaiseEvent Complete(False)
  239. End Sub
  240.